package com.cp.admin.api.controller;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.cp.admin.api.entity.CodeEnum;
import com.cp.admin.api.entity.Result;
import com.cp.admin.api.entity.bo.GroupAdminBO;
import com.cp.admin.api.entity.bo.UserRegisterBO;
import com.cp.admin.api.entity.vo.AlbumVO;
import com.cp.admin.api.entity.vo.OtherUserVO;
import com.cp.admin.api.entity.vo.UserInfoVO;
import com.cp.admin.api.entity.vo.UserVO;
import com.cp.admin.api.utils.*;
import com.cp.admin.core.shiro.ShiroKit;
import com.cp.admin.modular.system.model.User;
import com.cp.admin.modular.system.service.IUserService;
import com.cp.admin.modular.user.model.*;
import com.cp.admin.modular.user.service.*;
import com.cp.admin.modular.user.service.impl.UpImgServiceImpl;
import com.cp.admin.socket.MyWebSocket;
import com.cp.core.support.StrKit;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import jnr.ffi.annotations.In;
import lombok.extern.slf4j.Slf4j;
import okhttp3.WebSocket;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.websocket.Session;
import java.awt.*;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;

@Slf4j
@RestController
@RequestMapping("/user")
@Api(value = "用户操作", tags = "用户操作")
public class UserController extends BaseController {

    @Autowired
    private IUserBasicsService userService;
    @Autowired
    private IVipService vipService;
    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private IUserInfoService userInfoService;
    @Autowired
    private IUserFriendService friendService;
    @Autowired
    private IUserFriendGroupService friendGroupService;
    @Autowired
    private UpImgService upImgService;

    @ApiOperation("用户注册")
    @RequestMapping(value = "/register", method = RequestMethod.POST)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "account", value = "手机号", dataType = "String", required = true, paramType = "query"),
            @ApiImplicitParam(name = "password", value = "用户密码", dataType = "String", required = true, paramType = "query"),
            @ApiImplicitParam(name = "code", value = "邀请码", dataType = "String", required = true, paramType = "query"),
            @ApiImplicitParam(name = "smsCode", value = "验证码", dataType = "String", required = true, paramType = "query"),
            @ApiImplicitParam(name = "headImg", value = "用户头像", dataType = "String", required = true, paramType = "query")

    })
    public Result register(UserRegisterBO bo, String account, String password, String smsCode, String code, MultipartFile headImg) {
        //验证参数
        if (StrKit.isBlank(account) || StrKit.isBlank(password) || StrKit.isBlank(code) || headImg == null || StrKit.isBlank(smsCode)) {
            return new Result(CodeEnum.FAIL_10001);
        }
        //验证手机号
        UserBasics user1 = userService.selectOne(new EntityWrapper().eq("account", account));
        if (user1 != null) {
            return new Result(CodeEnum.USER_LOGIN_ERROR_5);
        }
        if (!account.matches("^1[3|4|5|7|8][0-9]{9}$")) {
            return new Result(CodeEnum.USER_LOGIN_ERROR_6);
        }
        //验证邀请码
        UserBasics user2 = userService.selectOne(new EntityWrapper().eq("code", code));
        if (user2 == null) {
            return new Result(CodeEnum.FAIL_10010);
        }
        //验证码
        if (!redisUtils.getCode(account).equals(smsCode)) {
            return new Result(CodeEnum.USER_LOGIN_ERROR_4);
        }
        //添加用户表
        String salt = ShiroKit.getRandomSalt(7);
        UserBasics user = new UserBasics();
        Long id = PKGeneratorUtils.getInstance().nextId();
        user.setId(id);
        user.setAccount(account);
        user.setCode(StrUtils.getRandomStr(6));
        try {
            String headImage = upImgService.updateHead(headImg,CodeEnum.FILEDIR_10.getMsg());
            user.setHeadImg(headImage);
        } catch (Exception e) {
        }
        user.setParentId(user2.getId());
        user.setSalt(salt);
        user.setContinuousLogin(0);
        user.setPassword(ShiroKit.md5(password, salt));
        user.setStatus(0);
        user.setPeasQuantity(new BigDecimal(0.00));
        user.setCreateTime(new Date());
        if (userService.insert(user)) {
            //添加用户详情表(注册不强制填写)
            UserInfo info = new UserInfo();
            info.setUserId(id);
            Integer gender = (bo.getGender() == null) ? 0 : bo.getGender();
            info.setGender(gender);//性别默认为男
            String niceName = (bo.getNickname() == null) ? "用户：" + account : bo.getNickname();
            info.setNickname(niceName);//昵称默认为手机号
            info.setUserHeight(bo.getUserHeight());
            info.setUserWeight(bo.getUserWeight());
            try {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                Date birthDate = (bo.getBirthDate() == null) ? sdf.parse("2000-01-01") : sdf.parse(bo.getBirthDate().toString());
                info.setBirthDate(birthDate);//出生日期默认为1970-01-01
            } catch (ParseException e) {
            }
            info.setCityId(bo.getCityId());
            info.setVocation(bo.getVocation());
            info.setResidentCity(bo.getResidentCity());
            info.setDdined(bo.getDdined());
            info.setIntroduce(bo.getIntroduce());
            info.setConstellatory(bo.getConstellatory());
            info.setCreateTime(new Date());
            userInfoService.insert(info);
            //生成用户vip表（默认非vip）
            Vip vip = new Vip();
            vip.setUserId(id);
            vip.setCreateTime(new Date());
            vip.setStatus(0);
            vip.setGetPeas(new BigDecimal(0));
            vip.setGetPeasToday(new BigDecimal(0));
            vip.setOrderTimes(0);
            vip.setRemainingDays(0);
            vip.setGetPeasStatus(0);
            if (vipService.insert(vip)) {
                UserBasics parentUser = userService.selectOne(new EntityWrapper().eq("code", code));
                parentUser.setPeasQuantity(parentUser.getPeasQuantity().add(new BigDecimal(25)));
                userService.updateById(parentUser);
            }
            //生成好友表
            UserFriend friend = new UserFriend();
            friend.setUserId(id);
            friend.setFriendNumber(0);
            friend.setGroupNumber(1);
            friend.setSpecialNumber(0);
            UserFriendGroup group = new UserFriendGroup();
            group.setId(PKGeneratorUtils.getInstance().nextId());
            group.setUserId(id);
            group.setGroupNumber(0);
            group.setStatus(0);
            group.setGroupName("我的好友");
            group.setCreateTime(new Date());
            if (friendService.insert(friend) && friendGroupService.insert(group)) {
                return new Result(CodeEnum.SUCCESS);
            }
        }
        return new Result(CodeEnum.FAIL);
    }


    @ApiOperation("短信验证")
    @RequestMapping(value = "/smsVerification", method = RequestMethod.POST)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "account", value = "手机号", dataType = "String", required = true, paramType = "query")
    })
    public Result smsVerification(String account) {
        if (account == null) {
            return new Result(CodeEnum.FAIL_10001);
        }
        if (!ValidateUtils.isMobile(account)) {
            return new Result(CodeEnum.USER_LOGIN_ERROR_6);
        }
        String code = ((int) ((Math.random() * 9) * 100000)) + "";
        fgSmsUtil.SendSms(account, code, "145883");
        redisUtils.setCode(account, code);
        return new Result();
    }


    @ApiOperation("用户详细信息修改")
    @RequestMapping(value = "/userInfoUpdate", method = RequestMethod.POST)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户Id", dataType = "String", required = true, paramType = "query")
    })
    public Result userInfoUpdate(UserRegisterBO bo, Long userId) {
        if (userId == null) {
            return new Result(CodeEnum.FAIL_10001);
        }
        UserInfo info = userInfoService.selectById(userId);
        UserBasics user = userService.selectOne(new EntityWrapper().eq("id", userId));
        if (info == null || user == null || user.getStatus() == 1) {
            return new Result(CodeEnum.FAIL_10003);
        }

        info.setGender(bo.getGender());
        info.setNickname(bo.getNickname());
        info.setUserHeight(bo.getUserHeight());
        info.setUserWeight(bo.getUserWeight());
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            info.setBirthDate(sdf.parse(bo.getBirthDate().toString()));
        } catch (ParseException e) {
        }
        info.setCityId(bo.getCityId());
        info.setVocation(bo.getVocation());
        info.setResidentCity(bo.getResidentCity());
        info.setDdined(bo.getDdined());
        info.setIntroduce(bo.getIntroduce());
        info.setConstellatory(bo.getConstellatory());
        info.setUpdateTime(new Date());
        if (!userInfoService.update(info, new EntityWrapper().eq("user_id", userId))) {
            return new Result(CodeEnum.FAIL);
        }
        return new Result(info);
    }


    @ApiOperation("用户登录")
    @RequestMapping(value = "/userLogin", method = RequestMethod.POST)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "account", value = "手机号", dataType = "String", required = true, paramType = "query"),
            @ApiImplicitParam(name = "password", value = "密码", dataType = "String", required = true, paramType = "query")
    })
    public Result userLogin(String account, String password) {
        if (StrKit.isBlank(account) || StrKit.isBlank(password)) {
            return new Result(CodeEnum.FAIL_10001);
        }

        UserBasics user = userService.selectOne(new EntityWrapper().eq("account", account));
        if (user == null) {
            return new Result(CodeEnum.USER_LOGIN_ERROR_3);
        }
        Boolean result = ShiroKit.md5(password, user.getSalt()).equals(user.getPassword());
        if (!result) {
            return new Result(CodeEnum.FAIL_10009);
        }
        if (user.getStatus() != 0) {
            return new Result(CodeEnum.FAIL_10003);
        }
        if (redisUtils.getUser(user.getId()) != null) {
            return new Result(CodeEnum.FAIL_10013);
        }
        //登录存redis
        UserInfo userInfo = userInfoService.selectById(user.getId());
        UserInfoVO userInfoVO = new UserInfoVO();
        userInfoVO.setId(user.getId());
        userInfoVO.setAccount(user.getAccount());
        userInfoVO.setPassword(user.getPassword());
        userInfoVO.setCode(user.getCode());
        userInfoVO.setSalt(user.getSalt());
        userInfoVO.setParentId(user.getParentId());
        userInfoVO.setHeadImg(user.getHeadImg());
        userInfoVO.setPeasQuantity(user.getPeasQuantity());
        userInfoVO.setStatus(user.getStatus());
        userInfoVO.setContinuousLogin(user.getContinuousLogin());

        userInfoVO.setBirthDate(userInfo.getBirthDate());
        userInfoVO.setCityId(userInfo.getCityId());
        userInfoVO.setGender(userInfo.getGender());
        userInfoVO.setNickname(userInfo.getNickname());
        userInfoVO.setUserHeight(userInfo.getUserHeight());
        userInfoVO.setUserWeight(userInfo.getUserWeight());
        userInfoVO.setConstellatory(userInfo.getConstellatory());
        userInfoVO.setResidentCity(userInfo.getResidentCity());
        userInfoVO.setIntroduce(userInfo.getIntroduce());
        userInfoVO.setVocation(userInfo.getVocation());
        userInfoVO.setDdined(userInfo.getDdined());
        redisUtils.setUser(userInfoVO);

        if (user.getUpdateTime() == null) {
            user.setUpdateTime(new Date());
            user.setContinuousLogin(1);
        } else {
            //获取登录时当天凌晨时间 计算与上次登录时间的差值
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(new Date());
            calendar.set(Calendar.HOUR_OF_DAY, 0);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
            Date zero = calendar.getTime();
            Long cha = zero.getTime() - user.getUpdateTime().getTime();
            if (cha < 86400000 && cha >= 0) {
                if (user.getContinuousLogin() <= 30) {
                    user.setContinuousLogin(user.getContinuousLogin() + 1);
                }
            } else if (cha > 86400000) {
                user.setContinuousLogin(1);
            }
            user.setUpdateTime(new Date());
        }
        userService.updateById(user);
        return new Result(CodeEnum.SUCCESS);
    }


    @ApiOperation("忘记密码/修改密码")
    @RequestMapping(value = "/forgetPassword", method = RequestMethod.POST)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "account", value = "手机号", dataType = "String", required = true, paramType = "query"),
            @ApiImplicitParam(name = "newPassword", value = "新密码", dataType = "String", required = true, paramType = "query"),
            @ApiImplicitParam(name = "smsCode", value = "验证码", dataType = "String", required = true, paramType = "query")
    })
    public Result forgetPassword(String account, String newPassword, String smsCode) {
        if (StrUtils.isEmpty(account) || StrUtils.isEmpty(newPassword)) {
            return new Result(CodeEnum.FAIL_10001);
        }
        UserBasics user = userService.selectOne(new EntityWrapper().eq("account", account));
        if (user == null) {
            return new Result(CodeEnum.USER_LOGIN_ERROR_2);
        }
        //验证码
        if (!redisUtils.getCode(account).equals(smsCode)) {
            return new Result(CodeEnum.USER_LOGIN_ERROR_4);
        }
        //修改密码
        String salt = user.getSalt();
        user.setPassword(ShiroKit.md5(newPassword, salt));
        Boolean result = userService.update(user, new EntityWrapper().eq("account", account));
        if (!result) {
            return new Result(CodeEnum.FAIL);
        }
        return new Result(CodeEnum.SUCCESS);
    }


    @ApiOperation("退出登录")
    @RequestMapping(value = "/personalCenter", method = RequestMethod.POST)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "用户ID", dataType = "String", required = true, paramType = "query")
    })
    public Result personalCenter(Long id) {
        redisUtils.delUser(id);
        return new Result(CodeEnum.SUCCESS);
    }

    @ApiOperation("查看个人中心")
    @RequestMapping(value = "/logout", method = RequestMethod.POST)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户ID", dataType = "String", required = true, paramType = "query")
    })
    public Result<UserVO> logout(Long userId) {
        if (userId == null) {
            return new Result<>(CodeEnum.FAIL_10001);
        }
        UserBasics me1 = userService.selectById(userId);
        UserInfo me2 = userInfoService.selectById(userId);
        if (me1 == null || me2 == null) {
            return new Result<>(CodeEnum.FAIL_10007);
        }
        UserVO vo = new UserVO();
        vo.setAccount(me1.getAccount());
        vo.setParentId(me1.getParentId());
        vo.setCode(me1.getCode());
        vo.setPeasQuantity(me1.getPeasQuantity());
        vo.setContinuousLogin(me1.getContinuousLogin());
        vo.setHeadImg(me1.getHeadImg());
        vo.setGender(me2.getGender());
        vo.setBirthDate(me2.getBirthDate());
        vo.setNickname(me2.getNickname());
        vo.setCityId(me2.getCityId());
        vo.setDdined(me2.getDdined());
        vo.setVocation(me2.getVocation());
        vo.setUserHeight(me2.getUserHeight());
        vo.setUserWeight(me2.getUserWeight());
        vo.setConstellatory(me2.getConstellatory());
        vo.setResidentCity(me2.getResidentCity());
        vo.setIntroduce(me2.getIntroduce());
        return new Result(vo);
    }

    @ApiOperation("查看其它用户信息")
    @RequestMapping(value = "/otherUser", method = RequestMethod.POST)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户ID", dataType = "String", required = true, paramType = "query")
    })
    public Result<OtherUserVO> applyFriend(Long userId) {
        if (userId == null) {
            return new Result(CodeEnum.FAIL_10001);
        }
        UserBasics user=userService.selectById(userId);
        if (user==null){
            return new Result(CodeEnum.FAIL_10007);
        }
        if (user.getStatus()!=1){
            return new Result(CodeEnum.FAIL_10003);
        }
        UserInfo info=userInfoService.selectById(userId);
        OtherUserVO vo=new OtherUserVO();
        vo.setHeadImg(user.getHeadImg());
        vo.setBirthDate(info.getBirthDate());
        vo.setCityId(info.getCityId());
        vo.setConstellatory(info.getConstellatory());
        vo.setDdined(info.getDdined());
        vo.setIntroduce(info.getIntroduce());
        vo.setVocation(info.getVocation());
        vo.setUserWeight(info.getUserWeight());
        vo.setUserHeight(info.getUserHeight());
        vo.setResidentCity(info.getResidentCity());
        vo.setNickname(info.getNickname());
        vo.setGender(info.getGender());
        return new Result<>(vo);
    }
}
